package com.kudian.restful.service;

import com.kudian.common.exception.ApplicationException;
import com.kudian.common.persistence.HibernateDao;
import com.kudian.common.persistence.Page;
import com.kudian.common.service.BaseService;
import com.kudian.common.utils.*;
import com.kudian.restful.common.Constant;
import com.kudian.restful.dao.*;
import com.kudian.restful.entity.*;
import com.kudian.restful.entity.Collection;
import com.kudian.restful.vo.comment.CommentInfoVO;
import com.kudian.restful.vo.goods.*;
import com.kudian.restful.vo.seller.ClientSellerComparator;
import com.kudian.restful.vo.seller.ClientSellerItemVO;
import com.kudian.restful.vo.seller.ClientSellerVO;
import com.spatial4j.core.shape.Rectangle;
import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Administrator on 2016/4/18.
 */
@Service
@Transactional(readOnly = true)
public class GoodsService extends BaseService<Goods, Integer> {
    private static final Logger logger = Logger.getLogger(SellerService.class);

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private GoodsPicDao goodsPicDao;

    @Autowired
    private LoginSessionDao loginSessionDao;

    @Autowired
    private MediaResDao mediaResDao;

    @Autowired
    private MediaResService mediaResService;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private SellerDao sellerDao;

    @Autowired
    private CollectionDao collectionDao;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private SellerService sellerService;

    @Autowired
    private GroupBuyDao groupBuyDao;

    @Override
    public HibernateDao<Goods, Integer> getEntityDao() {
        return goodsDao;
    }

    @Transactional(readOnly = false)
    public Integer saveGoodsAndPics(AddGoodsVO addGoodsVO) {
        Goods goods = new Goods();
        goods.setCatId(addGoodsVO.getCatId());
        goods.setGoodsSn(addGoodsVO.getGoodsSn());
        goods.setGoodsName(addGoodsVO.getGoodsName());
        goods.setShopPrice(addGoodsVO.getShopPrice());
        goods.setGoodsBrief(addGoodsVO.getGoodsBrief());
        goods.setGoodsDesc(addGoodsVO.getGoodsDesc());
        goods.setInventory(addGoodsVO.getInventory());
        goods.setMeasureUnit(addGoodsVO.getMeasureUnit());
        goods.setUnitDesc(addGoodsVO.getUnitDesc());
        goods.setSpeNote(addGoodsVO.getSpeNote());
        goods.setIsReal(addGoodsVO.getIsReal());
        goods.setIsOnSale(addGoodsVO.getIsOnSale());
        goods.setArea(addGoodsVO.getArea());
        goods.setSellerId(addGoodsVO.getSellerId());
        goods.setSellerNote(addGoodsVO.getSellerNote());

        // goods.setSortOrder(addgoodsvo.get);
        goods.setSortOrder(addGoodsVO.getSortOrder());
        goods.setIsDelete(false);

        goods.setBrandId((short) 0);
        goods.setClickCount(0);
        goods.setKeywords("");
        goods.setIsShipping(false);
        Timestamp t = new Timestamp(System.currentTimeMillis());
        goods.setAddTime(t);
        goods.setLastUpdate(t);
        goods.setIsBest(false);
        goods.setIsNew(false);
        goods.setIsHot(false);
        goods.setIsPromote(false);
        goods.setOldGoodsId(0);

        // 原价格
        if (addGoodsVO.getOriginalPrice() == null) {
            goods.setOriginalPrice(0.0);
        } else {
            goods.setOriginalPrice(addGoodsVO.getOriginalPrice());
        }
        // 团信息
        if (addGoodsVO.getGbTypeId() == null) {
            goods.setGbTypeId(0);
        } else {
            goods.setGbTypeId(addGoodsVO.getGbTypeId());
        }

        this.save(goods);
        if (StringUtils.isNotBlank(addGoodsVO.getPics())) {
            String[] pics = addGoodsVO.getPics().split(",");
            for (String pic : pics) {
                GoodsPic gp = new GoodsPic();
                gp.setGoodsId(goods.getGoodsId());
                gp.setIsDelete(false);
                gp.setLastTime(t);
                gp.setMediaId(pic);
                gp.setSortOrder((short) 0);
                gp.setDirection((short) 0);
                goodsPicDao.save(gp);
            }
        }

        if (StringUtils.isNotBlank(addGoodsVO.getBottomPics())) {
            String[] pics = addGoodsVO.getBottomPics().split(",");
            for (String pic : pics) {
                GoodsPic gp = new GoodsPic();
                gp.setGoodsId(goods.getGoodsId());
                gp.setIsDelete(false);
                gp.setLastTime(t);
                gp.setMediaId(pic);
                gp.setSortOrder((short) 0);
                gp.setDirection((short) 1);
                goodsPicDao.save(gp);
            }
        }
        return goods.getGoodsId();
    }

    @Transactional(readOnly = false)
    public Integer updateGoodsAndPics(UpdateGoodsVO updateGoodsVO) throws ApplicationException {
        LoginSession ent = loginSessionDao.get(updateGoodsVO.getAccess_token());
        if (ent == null) {
            throw new ApplicationException(9999, "access_token无效");
        }
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            throw new ApplicationException(9999, "此用户不是商家用户");
        }

        Goods g = this.goodsDao.findUnique(Restrictions.eq("goodsId", updateGoodsVO.getGoodsId()),
                Restrictions.eq("sellerId", s.getSellerId()));
        if (g == null) {
            throw new ApplicationException(9999, "此用户无此商品");
        }

        copyGoodsAndPics(updateGoodsVO.getGoodsId());
        Goods goods = this.get(updateGoodsVO.getGoodsId());
        goods.setCatId(updateGoodsVO.getCatId());
        goods.setGoodsSn(updateGoodsVO.getGoodsSn());
        goods.setGoodsName(updateGoodsVO.getGoodsName());
        goods.setShopPrice(updateGoodsVO.getShopPrice());
        goods.setGoodsBrief(updateGoodsVO.getGoodsBrief());
        goods.setGoodsDesc(updateGoodsVO.getGoodsDesc());
        goods.setInventory(updateGoodsVO.getInventory());
        goods.setMeasureUnit(updateGoodsVO.getMeasureUnit());
        goods.setUnitDesc(updateGoodsVO.getUnitDesc());
        goods.setSpeNote(updateGoodsVO.getSpeNote());
        goods.setIsReal(updateGoodsVO.getIsReal());
        goods.setIsOnSale(updateGoodsVO.getIsOnSale());
        goods.setArea(updateGoodsVO.getArea());
        goods.setSellerId(updateGoodsVO.getSellerId());
        goods.setSellerNote(updateGoodsVO.getSellerNote());
        goods.setSortOrder(updateGoodsVO.getSortOrder());
        goods.setIsDelete(false);

        goods.setBrandId((short) 0);
        goods.setClickCount(0);
        goods.setKeywords("");
        goods.setIsShipping(false);
        // goods.setAddTime(t);
        goods.setLastUpdate(new Timestamp(System.currentTimeMillis()));
        goods.setIsBest(false);
        goods.setIsNew(false);
        goods.setIsHot(false);
        goods.setIsPromote(false);
        goods.setOldGoodsId(0);
        // 原价格
        if (updateGoodsVO.getOriginalPrice() == null) {
            goods.setOriginalPrice(0.0);
        } else {
            goods.setOriginalPrice(updateGoodsVO.getOriginalPrice());
        }
        // 团信息
        if (updateGoodsVO.getGbTypeId() == null) {
            goods.setGbTypeId(0);
        } else {
            goods.setGbTypeId(updateGoodsVO.getGbTypeId());
        }
        this.save(goods);

        // 删除图片资源
        List<GoodsPic> gps = goodsPicDao.find(Restrictions.eq("goodsId", updateGoodsVO.getGoodsId()));
        for (GoodsPic gp : gps) {
            goodsPicDao.delete(gp);
        }

        if (StringUtils.isNotBlank(updateGoodsVO.getPics())) {
            String[] pics = updateGoodsVO.getPics().split(",");
            for (String pic : pics) {
                GoodsPic gp = new GoodsPic();
                gp.setGoodsId(goods.getGoodsId());
                gp.setIsDelete(false);
                gp.setLastTime(new Timestamp(System.currentTimeMillis()));
                gp.setMediaId(pic);
                gp.setSortOrder((short) 0);
                gp.setDirection((short) 0);
                goodsPicDao.save(gp);
            }
        }

        if (StringUtils.isNotBlank(updateGoodsVO.getBottomPics())) {
            String[] pics = updateGoodsVO.getBottomPics().split(",");
            for (String pic : pics) {
                GoodsPic gp = new GoodsPic();
                gp.setGoodsId(goods.getGoodsId());
                gp.setIsDelete(false);
                gp.setLastTime(new Timestamp(System.currentTimeMillis()));
                gp.setMediaId(pic);
                gp.setSortOrder((short) 0);
                gp.setDirection((short) 1);
                goodsPicDao.save(gp);
            }
        }
        return goods.getGoodsId();
    }

    public void copyGoodsAndPics(Integer goodsId) {
        Goods goods = this.get(goodsId);

        Goods cpgoods = new Goods();
        cpgoods.setCatId(goods.getCatId());
        cpgoods.setGoodsSn(goods.getGoodsSn());
        cpgoods.setGoodsName(goods.getGoodsName());
        cpgoods.setClickCount(goods.getClickCount());
        cpgoods.setBrandId(goods.getBrandId());
        cpgoods.setShopPrice(goods.getShopPrice());
        cpgoods.setOriginalPrice(goods.getOriginalPrice());
        cpgoods.setKeywords(goods.getKeywords());
        cpgoods.setGoodsBrief(goods.getGoodsBrief());
        cpgoods.setGoodsDesc(goods.getGoodsDesc());
        cpgoods.setInventory(goods.getInventory());
        cpgoods.setMeasureUnit(goods.getMeasureUnit());
        cpgoods.setUnitDesc(goods.getUnitDesc());
        cpgoods.setIsReal(goods.getIsReal());
        // cpgoods.setIsOnSale(goods.getIsOnSale());
        cpgoods.setIsOnSale(false);
        cpgoods.setIsShipping(goods.getIsShipping());
        cpgoods.setAddTime(goods.getAddTime());
        cpgoods.setSortOrder(goods.getSortOrder());
        // cpgoods.setIsDelete(goods.getIsDelete());
        cpgoods.setIsDelete(true);
        cpgoods.setIsBest(goods.getIsBest());
        cpgoods.setIsNew(goods.getIsNew());
        cpgoods.setIsHot(goods.getIsHot());
        cpgoods.setIsPromote(goods.getIsPromote());
        cpgoods.setLastUpdate(DateUtils.getSysTimestamp());
        cpgoods.setArea(goods.getArea());
        cpgoods.setSellerId(goods.getSellerId());
        cpgoods.setSellerNote(goods.getSellerNote());
        cpgoods.setSpeNote(goods.getSpeNote());
        // 原商品
        cpgoods.setOldGoodsId(goods.getGoodsId());
        cpgoods.setGbTypeId(goods.getGbTypeId());
        this.goodsDao.save(cpgoods);

        List<GoodsPic> gps = goodsPicDao.find(Restrictions.eq("goodsId", goodsId));
        for (GoodsPic gp : gps) {
            GoodsPic cpgp = new GoodsPic();
            cpgp.setGoodsId(cpgoods.getGoodsId());
            cpgp.setMediaId(gp.getMediaId());
            cpgp.setSortOrder(gp.getSortOrder());
            cpgp.setIsDelete(gp.getIsDelete());
            cpgp.setLastTime(DateUtils.getSysTimestamp());
            cpgp.setDirection(gp.getDirection());

            this.goodsPicDao.save(cpgp);
        }
    }

    @Transactional(readOnly = false)
    public void off(OffGoodsVO offGoodsVO) {
        LoginSession ent = loginSessionDao.get(offGoodsVO.getAccess_token());
        if (ent == null) {
            return;
        }
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            return;
        }

        Goods g = this.goodsDao.findUnique(Restrictions.eq("goodsId", offGoodsVO.getGoodsId()),
                Restrictions.eq("sellerId", s.getSellerId()));
        g.setIsOnSale(false);
        this.goodsDao.save(g);
    }

    @Transactional(readOnly = false)
    public void delete(DelGoodsVO delGoodsVO) {
        LoginSession ent = loginSessionDao.get(delGoodsVO.getAccess_token());
        if (ent == null) {
            return;
        }
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            return;
        }

        Goods g = this.goodsDao.findUnique(Restrictions.eq("goodsId", delGoodsVO.getGoodsId()),
                Restrictions.eq("sellerId", s.getSellerId()));
        g.setIsDelete(true);
        this.goodsDao.save(g);
    }

    @Transactional(readOnly = false)
    public void on(OnGoodsVO onGoodsVO) {
        LoginSession ent = loginSessionDao.get(onGoodsVO.getAccess_token());
        if (ent == null) {
            return;
        }
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            return;
        }

        Goods g = this.goodsDao.findUnique(Restrictions.eq("goodsId", onGoodsVO.getGoodsId()),
                Restrictions.eq("sellerId", s.getSellerId()));
        g.setIsOnSale(true);
        this.goodsDao.save(g);
    }

    /**
     * 根据返回的商品设置商品信息
     * @param gs
     * @return
     */
    public List<GoodsItemVO> queryGoodsInfos(List<Goods> gs) {
        List<Integer> goodsIds = new ArrayList<Integer>();
        List<GoodsItemVO> rets = new ArrayList<GoodsItemVO>();
        for (Goods g : gs) {
            GoodsItemVO item = new GoodsItemVO();
            item.setGoodsId(g.getGoodsId());
            item.setCatId(g.getCatId());
            Category category = categoryDao.get(g.getCatId());
            if (category != null) {
                item.setCatName(category.getCatName());
            }
            item.setGoodsSn(g.getGoodsSn());
//            String ext = "";
//            if (0 != g.getGbTypeId().intValue()) {
//                GroupBuy gb = groupBuyDao.get(g.getGbTypeId().intValue());
//                // ext = gb.getName();
//                // item.setGoodsName(g.getGoodsName() + "[" + ext + "]");
//            }

            item.setGoodsName(g.getGoodsName());
            item.setOriginalPrice(g.getOriginalPrice());
            // item.setGoodsName(g.getGoodsName());
            item.setClickCount(g.getClickCount());

            item.setShopPrice(g.getShopPrice());
            item.setGoodsBrief(g.getGoodsBrief());
            item.setGoodsDesc(g.getGoodsDesc());
            item.setSpeNote(g.getSpeNote());
            item.setIsReal(g.getIsReal());
            item.setIsOnSale(g.getIsOnSale());
            item.setSellerId(g.getSellerId());
            Seller s = sellerDao.get(g.getSellerId());
            if (s != null) {
                item.setSellerName(s.getName());
            }
            item.setIsopen(s.getIsopen() == null ? false : s.getIsopen());
            item.setSellerNote(g.getSellerNote());

            item.setMeasureUnit(g.getMeasureUnit());
            item.setUnitDesc(g.getUnitDesc());
            item.setInventory(g.getInventory());
            item.setArea(g.getArea());
            item.setSortOrder(g.getSortOrder());

            // 上架时间
            item.setAddTime(g.getAddTime());

            // 已售出,临时
            item.setSoldnum(0);
            // 取平均值
            item.setCommentRank((short)0);
            // 评论数
            item.setCommentCount(0);

            String h1 = "from GoodsPic gp where gp.goodsId=:goodsId and gp.isDelete=0 order by gp.sortOrder";
            Map<String, Object> p1 = new HashMap<String, Object>();
            p1.put("goodsId", g.getGoodsId());
            List<GoodsPic> gps = goodsPicDao.find(h1, p1);

            String pics = "";
            String bottomPics = "";
            boolean isFirst = false;
            boolean isBottomFirst = false;
            String srcPics = "";
            String srcBottomPics = "";
            for (GoodsPic gp : gps) {
                String url = mediaResService.getResUrl(gp.getMediaId());
                if (0 == gp.getDirection()) {
                    if (!isFirst) {
                        pics += url;
                        srcPics += gp.getMediaId();
                        isFirst = true;
                    } else {
                        pics += "," + url;
                        srcPics += "," + gp.getMediaId();
                    }
                } else if (1 == gp.getDirection()) {
                    if (!isBottomFirst) {
                        bottomPics += url;
                        srcBottomPics += gp.getMediaId();
                        isBottomFirst = true;
                    } else {
                        bottomPics += "," + url;
                        srcBottomPics += "," + gp.getMediaId();
                    }
                }
            }

            item.setSrcPics(srcPics);
            item.setSrcBottomPics(srcBottomPics);
            item.setPics(pics);
            item.setBottomPics(bottomPics);
            item.setGbTypeId(g.getGbTypeId());

            // 商品主键集
            goodsIds.add(g.getGoodsId());
            rets.add(item);
        }

        Map<Integer, Integer> mapSold = orderService.getNumByGoodses(goodsIds);
        Map<Integer, CommentInfoVO> mapComment = commentService.queryByGoodses(goodsIds);
        for (GoodsItemVO itm : rets) {
            if (mapSold != null && !mapSold.isEmpty()) {
                if (mapSold.containsKey(itm.getGoodsId())) {
                    itm.setSoldnum((Integer) mapSold.get(itm.getGoodsId()));
                }
            }

            if (mapComment != null && !mapComment.isEmpty()) {
                if (mapComment.containsKey(itm.getGoodsId())) {
                    CommentInfoVO cmt = mapComment.get(itm.getGoodsId());
                    // 取平均值
                    itm.setCommentRank(cmt.getCommentRank());
                    // 评论数
                    itm.setCommentCount(cmt.getCommentCount());
                }
            }
        }
        return rets;
    }

    /**
     * 根据商家ID，取得所有商品
     * @param sellerId
     * @return
     */
    public List<GoodsItemVO> queryGoodsBySellerId(Integer sellerId) {

        List<GoodsItemVO> rets = null;
        List<Goods> gs = goodsDao.find(Restrictions.eq("sellerId", sellerId), Restrictions.eq("gbTypeId", 0),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));

        return queryGoodsInfos(gs);
    }

    /**
     * 根据商家ID，取得所有商品
     * @param sellerId
     * @param pageNo 从1开始
     * @return
     */
    public Page<GoodsItemVO> queryGoodsBySellerId(Integer sellerId, Integer pageNo) {
logger.info("queryGoodsBySellerId=>" + System.currentTimeMillis());
//        List<GoodsItemVO> rets = null;
//        List<Goods> gs = goodsDao.find(Restrictions.eq("sellerId", sellerId),
//                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));
        Page<GoodsItemVO> ret = new Page<GoodsItemVO>();
        Page<Goods> page = new Page<Goods>();
        if (pageNo == null || pageNo.intValue() < 1) {
            page.setPageNo(1);
        } else {
            page.setPageNo(pageNo);
        }
        page.setPageSize(Constant.PAGE_SIZE);
        page.setOrder(Page.ASC);
        page.setOrderBy("goodsId");
        page = goodsDao.findPage(page, Restrictions.eq("sellerId", sellerId), Restrictions.eq("gbTypeId", 0),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));
        List<Goods> gs = page.getResult();

        List<GoodsItemVO> rs = queryGoodsInfos(page.getResult());
        ret.setResult(rs);
        ret.setPageNo(page.getPageNo());
        ret.setPageSize(page.getPageSize());
        ret.setTotalCount(page.getTotalCount());

 logger.info("queryGoodsBySellerId end=>" + System.currentTimeMillis());
        return ret;
    }

    /**
     * 根据商家ID和团ID，取得所有商品
     * @param sellerId
     * @param pageNo 从1开始
     * @return
     */
    public Page<GoodsItemVO> queryGoodsBySellerIdAndGroupId(Integer sellerId, Integer gbTypeId, Integer pageNo) {
        logger.info("queryGoodsBySellerIdAndGroupId=>" + System.currentTimeMillis());
        Page<GoodsItemVO> ret = new Page<GoodsItemVO>();
        Page<Goods> page = new Page<Goods>();
        if (pageNo == null || pageNo.intValue() < 1) {
            page.setPageNo(1);
        } else {
            page.setPageNo(pageNo);
        }
        page.setPageSize(Constant.PAGE_SIZE);
        page.setOrder(Page.ASC);
        page.setOrderBy("goodsId");
        page = goodsDao.findPage(page, Restrictions.eq("sellerId", sellerId), Restrictions.eq("gbTypeId", gbTypeId),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));
        List<Goods> gs = page.getResult();

        List<GoodsItemVO> rs = queryGoodsInfos(page.getResult());
        ret.setResult(rs);
        ret.setPageNo(page.getPageNo());
        ret.setPageSize(page.getPageSize());
        ret.setTotalCount(page.getTotalCount());

        logger.info("queryGoodsBySellerIdAndGroupId end=>" + System.currentTimeMillis());
        return ret;
    }

    /**
     * 根据商家ID，取得所有商品
     * @param sellerId
     * @param pageNo 从1开始
     * @return
     */
    public Page<GoodsItemVO> queryGoodsBySellerId(Integer sellerId, Integer pageNo, Integer catId) {
        logger.info("queryGoodsBySellerId=>" + System.currentTimeMillis());
        Page<GoodsItemVO> ret = new Page<GoodsItemVO>();
        Page<Goods> page = new Page<Goods>();
        if (pageNo == null || pageNo.intValue() < 1) {
            page.setPageNo(1);
        } else {
            page.setPageNo(pageNo);
        }
        page.setPageSize(Constant.PAGE_SIZE);
        page.setOrder(Page.ASC);
        page.setOrderBy("goodsId");
        page = goodsDao.findPage(page, Restrictions.eq("sellerId", sellerId), Restrictions.eq("catId", catId), Restrictions.eq("gbTypeId", 0),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));
        List<Goods> gs = page.getResult();

        List<GoodsItemVO> rs = queryGoodsInfos(page.getResult());
        ret.setResult(rs);
        ret.setPageNo(page.getPageNo());
        ret.setPageSize(page.getPageSize());
        ret.setTotalCount(page.getTotalCount());

        logger.info("queryGoodsBySellerId end=>" + System.currentTimeMillis());
        return ret;
    }

    /**
     * 获得登录者指定商店的商品列表, 商家版使用的目前不分页
     * @param queryGoodsVO
     * @return
     */
    public List<GoodsItemVO> queryGoodsAndPics(QueryGoodsVO queryGoodsVO) throws ApplicationException {
        LoginSession ent = loginSessionDao.find(queryGoodsVO.getAccess_token());
        if (ent == null) {
            throw new ApplicationException(9999, "access_token无效");
        }
        Seller s = sellerDao.findUnique(Restrictions.eq("sellerId", queryGoodsVO.getSellerId()), Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            throw new ApplicationException(9999, "此店铺不是此用户的!");
        }

        return queryGoodsBySellerId(queryGoodsVO.getSellerId());
    }

    public List<GoodsByCategoryVO> goodsByCategory(List<GoodsItemVO> infos) {
        List<GoodsByCategoryVO> rets = new ArrayList<GoodsByCategoryVO>();
        if (infos == null || infos.isEmpty()) {
            return rets;
        }

        Map<Integer, List<GoodsItemVO>> map = new HashMap<Integer, List<GoodsItemVO>>();
        for (GoodsItemVO vo : infos) {
            List<GoodsItemVO> gis = null;
            if (map.containsKey(vo.getCatId())) {
                gis = map.get(vo.getCatId());
            } else {
                gis = new ArrayList<GoodsItemVO>();
                map.put(vo.getCatId(), gis);
            }
            gis.add(vo);
        }

        for (Integer catId : map.keySet()) {
            GoodsByCategoryVO gbc = new GoodsByCategoryVO();
            gbc.setCatId(catId);
            Category cate = categoryDao.get(catId);
            if (cate != null) {
                gbc.setCatName(cate.getCatName());
            } else {
                gbc.setCatName("");
            }
            gbc.setItems(map.get(catId));

            rets.add(gbc);
        }
        return rets;
    }

    /**
     * 获得指定商店的商品明细
     * @param goodsId
     * @return
     */
    public GoodsItemVO details(Integer goodsId) {

        Goods g = goodsDao.get(goodsId);

        GoodsItemVO item = new GoodsItemVO();
        item.setGoodsId(g.getGoodsId());
        item.setCatId(g.getCatId());
        Category category = categoryDao.get(g.getCatId());
        if (category != null) {
            item.setCatName(category.getCatName());
        }
        item.setGoodsSn(g.getGoodsSn());

//        String ext = "";
//        if (0 != g.getGbTypeId().intValue()) {
//            GroupBuy gb = groupBuyDao.get(g.getGbTypeId().intValue());
//            ext = gb.getName();
//            item.setGoodsName(g.getGoodsName() + "[" + ext + "]");
//
//        } else {
//            item.setGoodsName(g.getGoodsName());
//            item.setGbTypeId(0);
//        }
        item.setGbTypeId(g.getGbTypeId());
        item.setGoodsName(g.getGoodsName());
        item.setClickCount(g.getClickCount());

        item.setShopPrice(g.getShopPrice());
        item.setOriginalPrice(g.getOriginalPrice());
        item.setGoodsBrief(g.getGoodsBrief());
        item.setGoodsDesc(g.getGoodsDesc());
        item.setSpeNote(g.getSpeNote());
        item.setIsReal(g.getIsReal());
        item.setIsOnSale(g.getIsOnSale());
        item.setSellerId(g.getSellerId());
        Seller s = sellerDao.get(g.getSellerId());
        if (s != null) {
            item.setSellerName(s.getName());
            item.setIsopen(s.getIsopen() == null ? false : s.getIsopen());
        }
        item.setSellerNote(g.getSellerNote());

        item.setMeasureUnit(g.getMeasureUnit());
        item.setUnitDesc(g.getUnitDesc());
        item.setSpeNote(g.getSpeNote());
        item.setInventory(g.getInventory());
        item.setArea(g.getArea());
        item.setSortOrder(g.getSortOrder());

        // 上架时间
        item.setAddTime(g.getAddTime());

        // 已售出,临时
        item.setSoldnum(orderService.getNumByGoods(g.getGoodsId()));
        CommentInfoVO cinfo = commentService.queryByGoods(g.getGoodsId());
        if (cinfo != null) {
            // 取平均值
            item.setCommentRank(cinfo.getCommentRank());
            // 评论数
            item.setCommentCount(cinfo.getCommentCount());
        } else {
            // 取平均值
            item.setCommentRank((short)0);
            // 评论数
            item.setCommentCount(0);
        }
        // 评价等级
        item.setCommentRank((short) 0);

        String h1 = "from GoodsPic gp where gp.goodsId=:goodsId and gp.isDelete=0 order by gp.sortOrder";
        Map<String, Object> p1 = new HashMap<String, Object>();
        p1.put("goodsId", g.getGoodsId());
        List<GoodsPic> gps = goodsPicDao.find(h1, p1);

        String pics = "";
        String bottomPics = "";

        boolean isFirst = false;
        boolean isBottomFirst = false;
        String srcPics = "";
        String srcBottomPics = "";
        for (GoodsPic gp : gps) {

            String url = mediaResService.getResUrl(gp.getMediaId());
            if (0 == gp.getDirection()) {
                if (!isFirst) {
                    pics += url;
                    srcPics += gp.getMediaId();
                    isFirst = true;
                } else {
                    pics += "," + url;
                    srcPics += "," + gp.getMediaId();
                }
            } else if (1 == gp.getDirection()) {
                if (!isBottomFirst) {
                    bottomPics += url;
                    srcBottomPics += gp.getMediaId();
                    isBottomFirst = true;
                } else {
                    srcBottomPics += "," + gp.getMediaId();
                    bottomPics += "," + url;
                }
            }
        }

        item.setSrcPics(srcPics);
        item.setSrcBottomPics(srcBottomPics);
        item.setPics(pics);
        item.setBottomPics(bottomPics);
        return item;
    }


    /**
     * 特产商品明细
     * 只查询上架商品
     * @param
     * @return
     */
    public Page<GoodsItemVO> spedetails(Integer pageNo) {

        PropertiesLoader loader = new PropertiesLoader("env.properties");
        int gtid = loader.getInteger("SPE_GT_ID", 0);
        Short spegtid = (short) gtid;
        List<Seller> ses = sellerDao.find(Restrictions.eq("gtId", spegtid));
        if (ses == null || ses.isEmpty())
            return null;
        Seller s = ses.get(0);
//        page = goodsDao.findPage(page, Restrictions.eq("sellerId", sellerId), Restrictions.eq("catId", catId),
//                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));

        Page<GoodsItemVO> ret = new Page<GoodsItemVO>();
        Page<Goods> page = new Page<Goods>();
        if (pageNo == null || pageNo.intValue() < 1) {
            page.setPageNo(1);
        } else {
            page.setPageNo(pageNo);
        }
        page.setPageSize(Constant.PAGE_SIZE);
        page.setOrder(Page.ASC);
        page.setOrderBy("goodsId");
        page = goodsDao.findPage(page, Restrictions.eq("sellerId", s.getSellerId()), Restrictions.eq("gbTypeId", 0),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));

        List<GoodsItemVO> goodsItem = getGoodsItemVOs(s, page.getResult());
        ret.setResult(goodsItem);
        ret.setPageNo(page.getPageNo());
        ret.setPageSize(page.getPageSize());
        ret.setTotalCount(page.getTotalCount());
        return ret;
    }

    /**
     * 在首页显示特产商品明细
     * 只查询上架商品
     * @param
     * @return
     */
    public List<GoodsItemVO> spedetailsinhomepage() {

        PropertiesLoader loader = new PropertiesLoader("env.properties");
        int gtid = loader.getInteger("SPE_GT_ID", 0);
        Short spegtid = (short) gtid;
        List<Seller> ses = sellerDao.find(Restrictions.eq("gtId", spegtid));
        if (ses == null || ses.isEmpty())
            return null;

        Seller s = ses.get(0);

        Page<Goods> page = new Page<Goods>();
        page.setPageNo(1);
        page.setPageSize(16);
        page = goodsDao.findPage(page, Restrictions.eq("sellerId", s.getSellerId()), Restrictions.eq("gbTypeId", 0),
                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));
        return getGoodsItemVOs(s, page.getResult());
    }

    private List<GoodsItemVO> getGoodsItemVOs(Seller s, List<Goods> gs) {

        List<GoodsItemVO> rets = new ArrayList<GoodsItemVO>();
        if (gs == null || gs.isEmpty()) {
            return rets;
        }

        for (Goods g : gs) {
            GoodsItemVO item = new GoodsItemVO();
            item.setGoodsId(g.getGoodsId());
            item.setCatId(g.getCatId());
            Category cg = categoryDao.get(g.getCatId());
            if (cg != null) {
                item.setCatName(cg.getCatName());
            }
            item.setGoodsSn(g.getGoodsSn());
            item.setGoodsName(g.getGoodsName());
            item.setClickCount(g.getClickCount());

            item.setShopPrice(g.getShopPrice());
            item.setOriginalPrice(g.getOriginalPrice());
            item.setGoodsBrief(g.getGoodsBrief());
            item.setGoodsDesc(g.getGoodsDesc());
            // 客户端不显示
            // item.setSpeNote(g.getSpeNote());
            item.setIsReal(g.getIsReal());
            item.setIsOnSale(g.getIsOnSale());
            item.setSellerId(g.getSellerId());
            if (s != null) {
                item.setSellerName(s.getName());
            }

            item.setSellerNote(g.getSellerNote());

            item.setMeasureUnit(g.getMeasureUnit());
            item.setUnitDesc(g.getUnitDesc());
            item.setInventory(g.getInventory());
            item.setArea(g.getArea());
            item.setSortOrder(g.getSortOrder());

            // 上架时间
            item.setAddTime(g.getAddTime());
            // 已售出,临时
            item.setSoldnum(orderService.getNumByGoods(g.getGoodsId()));
            CommentInfoVO cinfo = commentService.queryByGoods(g.getGoodsId());
            if (cinfo != null) {
                // 取平均值
                item.setCommentRank(cinfo.getCommentRank());
                // 评论数
                item.setCommentCount(cinfo.getCommentCount());
            } else {
                // 取平均值
                item.setCommentRank((short)0);
                // 评论数
                item.setCommentCount(0);
            }
            item.setGbTypeId(g.getGbTypeId());
            String h1 = "from GoodsPic gp where gp.goodsId=:goodsId and gp.isDelete=0 order by gp.sortOrder";
            Map<String, Object> p1 = new HashMap<String, Object>();
            p1.put("goodsId", g.getGoodsId());
            List<GoodsPic> gps = goodsPicDao.find(h1, p1);

            String pics = "";
            String bottomPics = "";

            boolean isFirst = false;
            boolean isBottomFirst = false;
            for (GoodsPic gp : gps) {

                String url = mediaResService.getResUrl(gp.getMediaId());
                if (0 == gp.getDirection()) {
                    if (!isFirst) {
                        pics += url;
                        isFirst = true;
                    } else {
                        pics += "," + url;
                    }
                } else if (1 == gp.getDirection()) {
                    if (!isBottomFirst) {
                        bottomPics += url;
                        isBottomFirst = true;
                    } else {
                        bottomPics += "," + url;
                    }
                }
            }

            item.setPics(pics);
            item.setBottomPics(bottomPics);
            rets.add(item);
        }
        return rets;
    }

    public Page<GoodsAroundItemVO> queryAroundByclient(GoodsAroundVO vo) {

        Page<GoodsAroundItemVO> gai = new Page<GoodsAroundItemVO>();
        gai.setResult(new ArrayList<GoodsAroundItemVO>());
        gai.setPageSize(Constant.PAGE_SIZE);
        if (vo.getPageNo() == null || vo.getPageNo().intValue() < 1) {
            gai.setPageNo(1);
        } else {
            gai.setPageNo(vo.getPageNo());
        }

        ClientSellerVO clientSellerVO = new ClientSellerVO();
        clientSellerVO.setLatitudes(vo.getLatitudes());
        clientSellerVO.setLongitudes(vo.getLongitudes());
        clientSellerVO.setGtId(vo.getGtId());
        // 取周边店铺
        List<ClientSellerItemVO> ls = sellerService.queryByClient(clientSellerVO);

        // 增加lbs功能
        if (ls == null || ls.isEmpty()) {
            return gai;
        }
        // 按距离排序
        ClientSellerComparator comparator = new ClientSellerComparator();
        Collections.sort(ls, comparator);

        // Map<Integer, Seller> map = new HashMap<Integer, Seller>();
        Map<Integer, GoodsSellerInfoVO> sellerCache = new HashMap<Integer, GoodsSellerInfoVO>();
        List<Integer> sellerIds = new ArrayList<Integer>();
        for (ClientSellerItemVO s : ls) {
            GoodsSellerInfoVO item = new GoodsSellerInfoVO();
            item.setSellerId(s.getSellerId());
            item.setName(s.getName());
            item.setSellerName(s.getName());
            item.setIsopen(s.getIsopen() == null ? false : s.getIsopen());
            item.setDistance(s.getDistance());
            item.setMinChange(s.getMinChange());
            item.setIsFirst(s.getIsFirst());
            item.setFirstAmount(s.getFirstAmount());
            item.setIsFullMinus(s.getIsFullMinus());
            item.setFullAmount(s.getFullAmount());
            item.setMinusAmount(s.getMinusAmount());
            item.setIsShippingFree(s.getIsShippingFree());
            item.setShippingFee(s.getShippingFee());

            sellerCache.put(s.getSellerId(), item);
            sellerIds.add(s.getSellerId());
        }

        // 分页
        List<Integer> goodsIds = new ArrayList<Integer>();
//        List<Goods> gs = goodsDao.find(Restrictions.in("sellerId", sellerIds),
//                Restrictions.eq("isDelete", false), Restrictions.eq("isOnSale", true));


        List<Goods> gs = findPageBySql(ls, gai);
        for (Goods g : gs) {

            String ext = "";

            GoodsAroundItemVO item = new GoodsAroundItemVO();
            item.setGoodsId(g.getGoodsId());
            item.setCatId(g.getCatId());
            item.setGoodsSn(g.getGoodsSn());

//            if (0 != g.getGbTypeId().intValue()) {
//                GroupBuy gb = groupBuyDao.get(g.getGbTypeId().intValue());
//                ext = gb.getName();
//                item.setGoodsName(g.getGoodsName() + "[" + ext + "]");
//            } else {
//                item.setGoodsName(g.getGoodsName());
//            }

            item.setGbTypeId(g.getGbTypeId());
            item.setGoodsName(g.getGoodsName());
            item.setClickCount(g.getClickCount());

            item.setShopPrice(g.getShopPrice());
            item.setOriginalPrice(g.getOriginalPrice());
            item.setGoodsBrief(g.getGoodsBrief());
            item.setGoodsDesc(g.getGoodsDesc());
            item.setSpeNote(g.getSpeNote());
            item.setIsReal(g.getIsReal());
            item.setIsOnSale(g.getIsOnSale());
            item.setSellerId(g.getSellerId());

            item.setSellerNote(g.getSellerNote());

            item.setMeasureUnit(g.getMeasureUnit());
            item.setUnitDesc(g.getUnitDesc());
            item.setInventory(g.getInventory());
            item.setArea(g.getArea());
            item.setSortOrder(g.getSortOrder());

            // 已售出,临时
            item.setSoldnum(0);
            // 取平均值
            item.setCommentRank((short)0);
            // 评论数
            item.setCommentCount(0);

            String h1 = "from GoodsPic gp where gp.goodsId=:goodsId and gp.isDelete=0 order by gp.sortOrder";
            Map<String, Object> p1 = new HashMap<String, Object>();
            p1.put("goodsId", g.getGoodsId());
            List<GoodsPic> gps = goodsPicDao.find(h1, p1);

            String pics = "";
            String bottomPics = "";

            boolean isFirst = false;
            boolean isBottomFirst = false;
            for (GoodsPic gp : gps) {
                String url = mediaResService.getResUrl(gp.getMediaId());
                if (0 == gp.getDirection()) {
                    if (!isFirst) {
                        pics += url;
                        isFirst = true;
                    } else {
                        pics += "," + url;
                    }
                } else if (1 == gp.getDirection()) {
                    if (!isBottomFirst) {
                        bottomPics += url;
                        isBottomFirst = true;
                    } else {
                        bottomPics += "," + url;
                    }
                }
            }
            item.setPics(pics);

            goodsIds.add(item.getGoodsId());
            gai.getResult().add(item);
        }

        Map<Integer, Integer> mapSold = orderService.getNumByGoodses(goodsIds);
        Map<Integer, CommentInfoVO> mapComment = commentService.queryByGoodses(goodsIds);
        for (GoodsAroundItemVO itm : gai.getResult()) {
            if (mapSold != null && !mapSold.isEmpty()) {
                if (mapSold.containsKey(itm.getGoodsId())) {
                    itm.setSoldnum((Integer) mapSold.get(itm.getGoodsId()));
                }
            }

            if (mapComment != null && !mapComment.isEmpty()) {
                if (mapComment.containsKey(itm.getGoodsId())) {
                    CommentInfoVO cmt = mapComment.get(itm.getGoodsId());
                    // 取平均值
                    itm.setCommentRank(cmt.getCommentRank());
                    // 评论数
                    itm.setCommentCount(cmt.getCommentCount());
                }
            }
        }

        // 从缓存中取店铺信息
        for (GoodsAroundItemVO item : gai.getResult()) {
            GoodsSellerInfoVO s = sellerCache.get(item.getSellerId());

            item.setSellerId(s.getSellerId());
            item.setName(s.getName());
            item.setSellerName(s.getName());
            item.setIsopen(s.getIsopen() == null ? false : s.getIsopen());
            item.setDistance(s.getDistance());

            item.setMinChange(s.getMinChange());

            item.setIsFirst(s.getIsFirst());
            item.setFirstAmount(s.getFirstAmount());
            item.setIsFullMinus(s.getIsFullMinus());
            item.setFullAmount(s.getFullAmount());
            item.setMinusAmount(s.getMinusAmount());
            item.setIsShippingFree(s.getIsShippingFree());
            item.setShippingFee(s.getShippingFee());
        }

        return gai;
    }

    private List<Goods> findPageBySql(List<ClientSellerItemVO> ls, Page<GoodsAroundItemVO> page) {
        List<Goods> goodses = new ArrayList<Goods>();
        if (ls == null || ls.isEmpty()) {
            return goodses;
        }

        StringBuffer sb = new StringBuffer();
        int size = ls.size();
        int offsize = 0;
        for (ClientSellerItemVO s : ls) {
            sb.append("select * from goods where seller_id = ");
            sb.append(s.getSellerId());
            sb.append("\n");
            sb.append("and is_delete=0 and is_on_sale=1 ");

            if (offsize != size - 1) {
                sb.append("union ALL ");
            }
            offsize++;
        }

        // 取总和
        String sqlCount = "select count(*) from (" + sb.toString() + ") t";
        SQLQuery query = this.goodsDao.createSQLQuery(sqlCount);
        long count = Integer.parseInt(query.uniqueResult().toString());
        page.setTotalCount(count);

        // 分页
        // int first = ((page.getPageNo() - 1) * page.getPageSize()) + 1;
        int first = ((page.getPageNo() - 1) * page.getPageSize());
        sb.append("limit " + first + ", " + Constant.PAGE_SIZE);
        SQLQuery query1 = goodsDao.createSQLQuery(sb.toString());
        List<Object[]> objs = (List<Object[]>) query1.list();
        for (Object[] obj : objs) {
            Integer goodsId = (Integer) obj[0];
            Goods g = this.goodsDao.get(goodsId);
            goodses.add(g);
        }
        return goodses;
    }

    public int isCollection(String access_token, Integer goodsId) {
        if (StringUtils.isBlank(access_token)) {
            return 0;
        }
        LoginSession ent = loginSessionDao.get(access_token);
        if (ent == null) {
            return 0;
        }

        List<Collection> cs = collectionDao.find(Restrictions.eq("userId", ent.getUserId()),
                Restrictions.eq("sellerId", 0), Restrictions.eq("goodsId", goodsId));
        if (cs == null || cs.isEmpty()) {
            return 0;
        }

        return cs.get(0).getCollectionId();
    }

}
